<div class="tmd-doc">
<h1 class="tmd-header-1">
Memory Leaking Scenarios
</h1>
<p></p>
<div class="tmd-usual">
When programming in a language supporting auto garbage collection, generally we don't need care about memory leaking problems, for the runtime will collect unused memory regularly. However, we do need to be aware of some special scenarios which may cause kind-of or real memory leaking. The remaining of the current article will list several such scenarios.
</div>
<p></p>
<h3 id="substring" class="tmd-header-3">
Kind-of Memory Leaking Caused by Substrings
</h3>
<p></p>
<div class="tmd-usual">
Go specification doesn't specify whether or not the result string and base string involved in a substring expression should share the same underlying <a href="memory-block.html">memory block</a> to host <a href="string.html">the underlying byte sequences</a> of the two strings. The standard Go compiler/runtime does let them share the same underlying memory block. This is a good design, which is both memory and CPU consuming wise. But it may cause kind-of memory leaking sometimes.
</div>
<p></p>
<p></p>
<div class="tmd-usual">
For example, after the <code class="tmd-code-span">demo</code> function in the following example is called, there will be about 1M bytes memory leaking (kind of), until the package-level variable <code class="tmd-code-span">s0</code> is modified again elsewhere.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">var s0 string // a package-level variable

// A demo purpose function.
func f(s1 string) {
	s0 = s1[:50]
	// Now, s0 shares the same underlying memory block
	// with s1. Although s1 is not alive now, but s0
	// is still alive, so the memory block they share
	// couldn't be collected, though there are only 50
	// bytes used in the block and all other bytes in
	// the block become unavailable.
}

func demo() {
	s := createStringWithLengthOnHeap(1 &lt;&lt; 20) // 1M bytes
	f(s)
}
</code></pre>
<p></p>
<div class="tmd-usual">
To avoid this kind-of memory leaking, we can convert the substring to a <code class="tmd-code-span">[]byte</code> value then convert the <code class="tmd-code-span">[]byte</code> value back to <code class="tmd-code-span">string</code>.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">func f(s1 string) {
	s0 = string([]byte(s1[:50]))
}
</code></pre>
<p></p>
<div class="tmd-usual">
The drawback of the above way to avoid the kind-of memory leaking is there are two 50-byte duplicates which happen in the conversion process, one of them is unnecessary.
</div>
<p></p>
<div class="tmd-usual">
We can make use of one of <a href="string.html#conversion-optimizations">the optimizations</a> made by the standard Go compiler to avoid the unnecessary duplicate, with a small extra cost of one byte memory wasting.
</div>
<p></p>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">func f(s1 string) {
	s0 = (" " + s1[:50])[1:]
}
</code></pre>
<p></p>
<div class="tmd-usual">
The disadvantage of the above way is the compiler optimization may become invalid later, and the optimization may be not available from other compilers.
</div>
<p></p>
<div class="tmd-usual">
The third way to avoid the kind-of memory leaking is to utilize the <code class="tmd-code-span">strings.Builder</code> supported since Go 1.10.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">import "strings"

func f(s1 string) {
	var b strings.Builder
	b.Grow(50)
	b.WriteString(s1[:50])
	s0 = b.String()
}
</code></pre>
<p></p>
<div class="tmd-usual">
The disadvantage of the third way is it is a little verbose (by comparing to the first two ways). A good news is, since Go 1.12, we can call the <code class="tmd-code-span">Repeat</code> function with the <code class="tmd-code-span">count</code> argument as <code class="tmd-code-span">1</code> in the <code class="tmd-code-span">strings</code> standard package to clone a string. Since Go 1.12, the underlying implementation of <code class="tmd-code-span">strings.Repeat</code> will make use of <code class="tmd-code-span">strings.Builder</code>, to avoid one unnecessary duplicate.
</div>
<p></p>
<div class="tmd-usual">
Since Go 1.18, a <code class="tmd-code-span">Clone</code> function has been added to the <code class="tmd-code-span">strings</code> standard package. It becomes the best way to do this job.
</div>
<p></p>
<h3 id="subslice" class="tmd-header-3">
Kind-of Memory Leaking Caused by Subslices
</h3>
<p></p>
<div class="tmd-usual">
Similarly to substrings, subslices may also cause kind-of memory leaking. In the following code, after the <code class="tmd-code-span">g</code> function is called, most memory occupied by the memory block hosting the elements of <code class="tmd-code-span">s1</code> will be lost (if no more values reference the memory block).
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">var s0 []int

func g(s1 []int) {
	// Assume the length of s1 is much larger than 30.
	s0 = s1[len(s1)-30:]
}
</code></pre>
<p></p>
<div class="tmd-usual">
If we want to avoid the kind-of memory leaking, we must duplicate the 30 elements for <code class="tmd-code-span">s0</code>, so that the aliveness of <code class="tmd-code-span">s0</code> will not prevent the memory block hosting the elements of <code class="tmd-code-span">s1</code> from being collected.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">func g(s1 []int) {
	s0 = make([]int, 30)
	copy(s0, s1[len(s1)-30:])
	// Now, the memory block hosting the elements
	// of s1 can be collected if no other values
	// are referencing the memory block.
}
</code></pre>
<p></p>
<h3 id="dead-slice-elements" class="tmd-header-3">
Kind-of Memory Leaking Caused by Not Resetting Pointers in Lost Slice Elements
</h3>
<p></p>
<div class="tmd-usual">
In the following code, after the <code class="tmd-code-span">h</code> function is called, the memory block allocated for the first and the last elements of slice <code class="tmd-code-span">s</code> will get lost.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">func h() []*int {
	s := []*int{new(int), new(int), new(int), new(int)}
	// do something with s ...

	return s[1:3:3]
}
</code></pre>
<p></p>
<div class="tmd-usual">
As long as the returned slice is still alive, it will prevent any elements of <code class="tmd-code-span">s</code> from being collected, which in consequence prevents the two memory blocks allocated for the two <code class="tmd-code-span">int</code> values referenced by the first and the last elements of <code class="tmd-code-span">s</code> from being collected.
</div>
<p></p>
<div class="tmd-usual">
If we want to avoid such kind-of memory leaking, we must reset the pointers stored in the lost elements.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">func h() []*int {
	s := []*int{new(int), new(int), new(int), new(int)}
	// do something with s ...

	// Reset pointer values.
	s[0], s[len(s)-1] = nil, nil
	return s[1:3:3]
}
</code></pre>
<p></p>
<div class="tmd-usual">
We often need to reset the pointers for some old slice elements in <a href="container.html#slice-manipulations">slice element deletion operations</a>.
</div>
<p></p>
<p></p>
<h3 id="hanging-goroutine" class="tmd-header-3">
Real Memory Leaking Caused by Hanging Goroutines
</h3>
<p></p>
<div class="tmd-usual">
Sometimes, some goroutines in a Go program may stay in blocking state for ever. Such goroutines are called hanging goroutines. Go runtime will not kill hanging goroutines, so the resources allocated for (and the memory blocks referenced by) the hanging goroutines will never get garbage collected.
</div>
<p></p>
<div class="tmd-usual">
There are two reasons why Go runtime will not kill hanging goroutines. One is that sometimes it is hard for Go runtime to judge whether or not a blocking goroutine will be blocked for ever. The other is sometimes we deliberately make a goroutine hanging. For example, sometimes we may let the main goroutine of a Go program hang to avoid the program exiting.
</div>
<p></p>
<div class="tmd-usual">
We should avoid hanging goroutines which are caused by some logic mistakes in code design.
</div>
<p></p>
<h3 class="tmd-header-3">
Real Memory Leaking Caused by Not Stopping <code class="tmd-code-span">time.Ticker</code> Values Which Are Not Used Any More
</h3>
<p></p>
<div class="tmd-usual">
When a <code class="tmd-code-span">time.Timer</code> value is not used any more, it will be garbage collected after some time. But this is not true for a <code class="tmd-code-span">time.Ticker</code> value. We should stop a <code class="tmd-code-span">time.Ticker</code> value when it is not used any more.
</div>
<p></p>
<h3 class="tmd-header-3">
Real Memory Leaking Caused by Using Finalizers Improperly
</h3>
<p></p>
<div class="tmd-usual">
Setting a finalizer for a value which is a member of a cyclic reference group may <a href="https://golang.org/pkg/runtime/#SetFinalizer">prevent all memory blocks allocated for the cyclic reference group from being collected</a>. This is real memory leaking, not kind of.
</div>
<p></p>
<p></p>
<div class="tmd-usual">
For example, after the following function is called and exits, the memory blocks allocated for <code class="tmd-code-span">x</code> and <code class="tmd-code-span">y</code> are not guaranteed to be garbage collected in future garbage collecting.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">func memoryLeaking() {
	type T struct {
		v [1&lt;&lt;20]int
		t *T
	}

	var finalizer = func(t *T) {
		 fmt.Println("finalizer called")
	}

	var x, y T

	// The SetFinalizer call makes x escape to heap.
	runtime.SetFinalizer(&amp;x, finalizer)

	// The following line forms a cyclic reference
	// group with two members, x and y.
	// This causes x and y are not collectable.
	x.t, y.t = &amp;y, &amp;x // y also escapes to heap.
}
</code></pre>
<p></p>
<div class="tmd-usual">
So, please avoid setting finalizers for values in a cyclic reference group.
</div>
<p></p>
<div class="tmd-usual">
By the way, we <a href="unofficial-faq.html#finalizers">shouldn't use finalizers as object destructors</a>.
</div>
<p></p>
<p></p>
<h3 class="tmd-header-3">
Kind-of Resource Leaking by Deferring Function Calls
</h3>
<p></p>
<div class="tmd-usual">
Please read <a href="defer-more.html#kind-of-resource-leaking">this article</a> for details.
</div>
<p></p>
<p></p>
<p></p>
</div>
